package com.zhipin.hackthon;

import java.util.*;

public class User {

    /**
     * 权益集合
     */
    private List<Rights> rightsList;

    /**
     * 每个城市可以使用的权益id集合
     */
    private Map<String, List<Integer>> cityCanUseRightsListMap;

    /**
     * 权益使用可能
     */
    private Set<UseCase> useCases;

    private List<String> publishCityList = new ArrayList<>();

    public User(List<Rights> rightsList) {
        this.rightsList = rightsList;

        // 初始化放入没有使用的情况
        useCases = new HashSet<>();
        useCases.add(new UseCase(rightsList, 0));

        // 每个城市可以使用的权益
        cityCanUseRightsListMap = new HashMap<>();
        for (int rightsId = 0; rightsId < rightsList.size(); rightsId++) {
            for (String city : rightsList.get(rightsId).getCitySet()) {
                cityCanUseRightsListMap.computeIfAbsent(city, key -> new ArrayList<>())
                        .add(rightsId);
            }
        }
    }

    /**
     * @param city 职位的城市
     * @return false 发布失败; true发布成功
     */
    public boolean publishJob(String city) {
        publishCityList.add(city);

        // 城市可以使用的权益
        List<Integer> canUseRightsList = cityCanUseRightsListMap.get(city);
        if (canUseRightsList == null || canUseRightsList.isEmpty()) {
            return false;
        }

        // 在之前可能的情况的基础上，加入发布后可能的情况
        Set<UseCase> newUseCases = new HashSet<>();
        for (UseCase useCase : useCases) {
            for (int rightsId : canUseRightsList) {
                if (useCase.remainMap[rightsId] > 0) {
                    UseCase newCase = useCase.copy();
                    newCase.useList[newCase.useList.length - 1] = rightsId;
                    newCase.remainMap[rightsId]--;
                    newUseCases.add(newCase);
                }
            }
        }

        if (!newUseCases.isEmpty()) {
            useCases = newUseCases;
            return true;
        }

        return false;
    }

    /**
     * @return 权益占用结果列表
     */
    public List<RightsUse> getRightsUseList() {
        if (useCases.isEmpty()) {
            return Collections.emptyList();
        }

        int[] useList = useCases.iterator().next().useList;
        List<RightsUse> resultList = new ArrayList<>(useList.length);
        for (int i = 0; i < useList.length; i++) {
            String city = publishCityList.get(i);
            Rights rights = rightsList.get(useList[i]);
            resultList.add(new RightsUse(city, rights));
        }

        return resultList;
    }

    /**
     * 权益使用情况封装,根据权益剩余情况去重复
     */
    private static class UseCase {
        // 用数组可读性差，但是性能好，另一个版本User2用的是List和Map
        private int[] useList;
        private int[] remainMap;

        private UseCase() {
        }

        private UseCase(List<Rights> rightsList, int resultLen) {
            this.useList = new int[resultLen];

            this.remainMap = new int[rightsList.size()];
            for (int rightsId = 0; rightsId < rightsList.size(); rightsId++) {
                this.remainMap[rightsId] = rightsList.get(rightsId).getCount();
            }
        }

        private UseCase copy() {
            UseCase newUseCase = new UseCase();
            newUseCase.useList = Arrays.copyOf(useList, useList.length + 1);
            newUseCase.remainMap = Arrays.copyOf(remainMap, remainMap.length);
            return newUseCase;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            UseCase useCase = (UseCase) o;
            return Arrays.equals(remainMap, useCase.remainMap);
        }

        @Override
        public int hashCode() {
            return Arrays.hashCode(remainMap);
        }

        @Override
        public String toString() {
            return Arrays.toString(useList);
        }
    }
}
